
import os
import sys


temp_dir = os.path.abspath(__file__)
for i in range(4):
    temp_dir = os.path.dirname(temp_dir)
sys.path.append(temp_dir)
from dexen.system import constants
from dexen.system.client import frontend

EXIT = "Exit"
PREV_MENU = "Back to previous menu"
EXECUTE = "Execute"


main_menu_items = [
   "Setup new schema", 
   "Setup new population", 
   "Run batch tasks",
   "Run task", 
   "View running tasks",
   "View all schemas",
   "View all populations" 
]
initial_main_menu_items = [
    "Connect to server" 
]


def insert_indent(depth):
    for i in range(depth - 1):
        print "\t",

def insert_symbol(depth, symbol):
    symbol_str = ""
    depth = 1
    for i in range(depth):
        symbol_str += symbol
    print symbol_str,
        
def print_menu(msg, depth, symbol):
    insert_indent(depth)
    insert_symbol(depth, symbol)
    print msg

def print_selection(depth, symbol):
    print_menu("", depth, symbol)
    insert_indent(depth)
    insert_symbol(depth, symbol)
    print "Menu Item #:",

def print_title(title, depth, symbol):
    insert_indent(depth)
    insert_symbol(depth, symbol)
    print "___", title.upper(), "___"
    
def itemize_menu(menu_items_arg, title, depth, symbol):
    print "\n"
    print_title(title, depth, symbol)
    
    if depth == 1:
        menu_items = [EXIT] + menu_items_arg
    else:
        menu_items = [PREV_MENU] + menu_items_arg
        
    for i, item in enumerate(menu_items):
        print_menu(str(i) + ".  " + item, depth, symbol)
    while True:
        print_selection(depth, symbol)
        menu_item = raw_input()
        
        if not menu_item.isdigit():
            print_menu("Please enter a number", depth, symbol)
            continue
        menu_no = int(menu_item)
        if menu_no < 0 or menu_no >= len(menu_items):
            print_menu("Please choose a menu # in valid range", depth, symbol)
            continue
        return menu_items[menu_no]

def execute_menu(depth, symbol):
    menu_items = [
        EXECUTE
    ]
    title = "Execute Menu"
    item = itemize_menu(menu_items, title, depth, symbol)
    return item

def type_line(msg, depth, symbol):
    print_menu("", depth, symbol)
    insert_indent(depth)
    insert_symbol(depth, symbol)
    print msg, 

def connect_to_server_menu():
    global initial_main_menu_items
    menu_items = [
        "Local Machine",
        "Remote Machine"
    ]
    title = "Connect to Server"
    depth = 2
    symbol = ">"
    while True:
        item = itemize_menu(menu_items, title, depth, symbol)
        if item == PREV_MENU:
            return
        if item == menu_items[0]:
            exec_item = execute_menu(depth+1, symbol)
            if exec_item == EXECUTE:
                frontend.connect_to_server("localhost")
                initial_main_menu_items = main_menu_items
                return
        if item == menu_items[1]:
            type_line("Type in the remote IP:", depth, symbol)
            ip_remote = raw_input()
            exec_item = execute_menu(depth+1, symbol)
            if exec_item == EXECUTE:
                frontend.connect_to_server(ip_remote)
                initial_main_menu_items = main_menu_items
                return

def setup_new_schema_menu():
    menu_items = [
        "Select folder"
    ]
    title = "Setup new schema"
    symbol = ">"
    while True:
        depth = 2
        item = itemize_menu(menu_items, title, depth, symbol)
        if item == PREV_MENU:
            return
        if item == menu_items[0]:
            depth += 1
            while True:
                schema_folders = frontend.getLocalSchemaFolderNames()
                it2 = itemize_menu(schema_folders, "Select folder", depth, symbol)
                if it2 == PREV_MENU:
                    break
                schema_folder = it2
                #type_line("Specify schema name:", depth, symbol)
                #schema_name = raw_input()
                schema_name = schema_folder
                try:
                    if execute_menu(depth+1, symbol) == EXECUTE:
                        frontend.create_new_schema(schema_name, schema_folder)
                        return
                except:
                    print_menu("The schema is already defined. Please choose another one.", depth+1, symbol)
            
def setup_new_population_menu():
    menu_items = [
        "Select Schema"
    ]
    title = "Setup new population"
    symbol = ">"
    while True:
        depth = 2
        item = itemize_menu(menu_items, title, depth, symbol)
        if item == PREV_MENU:
            return
        if item == menu_items[0]:
            while True:
                depth = 3
                schema_names = frontend.get_schema_names()
                it2 = itemize_menu(schema_names, "Select Schema", depth, symbol)
                if it2 == PREV_MENU:
                    break
                schema_name = it2
                #type_line("Specify population name:", depth, symbol)
                #pop_name = raw_input()
                while True:
                    depth = 4
                    #schema_file_names = frontend.getLocalSchemaFileNames(schema_name)
                    #it3 = itemize_menu(schema_file_names, title, depth, symbol)
                    
                    startup_func_names = frontend.getStartupFunctionNames(schema_name)
                    it3 = itemize_menu(startup_func_names, title, depth, symbol)
                    if it3 == PREV_MENU:
                        break
                    #file_name = it3
                    startup_func_name = it3
                    #pop_name = frontend.assignPopName(schema_name, file_name) 
                    pop_name = frontend.assign_pop_name(schema_name, func_name=startup_func_name)
                    if execute_menu(depth+1, symbol) == EXECUTE:
                        #frontend.runSettings(schema_name, pop_name, file_name)
                        frontend.runStartupFunction(schema_name, pop_name, startup_func_name)
                        return

def run_batch_tasks_menu():
    menu_items = frontend.getAllPopulationNames()
    title = "Run automated scripts"
    symbol = ">"

    while True:
        depth = 2
        item = itemize_menu(menu_items, title, depth, symbol)
        if item == PREV_MENU:
            return
        schema_name = item.split(", ")[0]
        pop_name = item.split(", ")[1]
        assert schema_name in frontend.get_schema_names()
        assert pop_name in frontend.get_population_names(schema_name)
        while True:
            depth = 3
            autostart_func_names = frontend.getAutoStartFunctionNames(schema_name)
            item = itemize_menu(autostart_func_names, title, depth, symbol)
            if item == PREV_MENU:
                break
            autostart_func_name = item            
            if execute_menu(depth+1, symbol) == EXECUTE:
                frontend.run_batch_tasks(schema_name, pop_name, autostart_func_name)
                return
        
def run_task_menu():
    menu_items = [
        "Select Schema"
    ]
    title = "Run schema script"
    symbol = ">"
    while True:
        depth = 2
        item = itemize_menu(menu_items, title, depth, symbol)
        if item == PREV_MENU:
            return
        if item == menu_items[0]:
            while True:
                depth = 3
                schema_names = frontend.get_schema_names()
                it2 = itemize_menu(schema_names, "Select Schema", depth, symbol)
                if it2 == PREV_MENU:
                    break
                schema_name = it2
                while True:
                    depth = 4
                    pop_names = frontend.get_population_names(schema_name)
                    it3 = itemize_menu(pop_names, "Select population", depth, symbol)
                    if it3 == PREV_MENU:
                        break
                    pop_name = it3
                    while True:
                        depth = 5
                        script_names = frontend.get_script_names(schema_name, pop_name)
                        it4 = itemize_menu(script_names, "Select script", depth, symbol)
                        if it4 == PREV_MENU:
                            break
                        script_name = it4
                        while True:
                            depth = 6
                            run_items = ["Run once", "Run loop"]
                            it5 = itemize_menu(run_items, "Running Type", depth, symbol)
                            if it5 == PREV_MENU:
                                break
                            if it5 == run_items[0]:
                                run_times = constants.ONCE
                            if it5 == run_items[1]:
                                run_times = constants.LOOPED
                            #id = 0 
                            """ BE WARNED ABOUT ID !!!! """
                            if execute_menu(depth+1, symbol) == EXECUTE:
                                frontend.run_task(schema_name, pop_name, script_name, run_times)
                                break
    
def stop_task_menu():
    title = "Stop schema script"
    symbol = ">"
    while True:
        depth = 2
        menu_items = frontend.getLocalRunningScripts()
        item = itemize_menu(menu_items, title, depth, symbol)
        if item == PREV_MENU:
            break
        script_identifier = item
        if execute_menu(depth+1, symbol) == EXECUTE:
            frontend.stop_script(script_identifier)
            return

def itemize_view_menu(menu_items, title, depth, symbol):
    print "\n"
    print_title(title, depth, symbol)
    for i, item in enumerate(menu_items):
        print_menu(str(i+1) + ". " + item, depth, symbol)
    print_menu("", depth, symbol)
    print_menu("Press Enter to return to the previous menu", depth, symbol)
    raw_input()

def view_running_tasks_menu():
    title = "View running schema scripts"
    symbol = ">"
    depth = 2
    menu_items = frontend.getLocalRunningScripts()
    itemize_view_menu(menu_items, title, depth, symbol)
    
def view_all_schemas_menu():
    title = "View all schemas"
    symbol = ">"
    depth = 2
    menu_items = frontend.get_schema_names()
    itemize_view_menu(menu_items, title, depth, symbol)

def view_all_populations_menu():
    title = "View all populations"
    symbol = ">"
    depth = 2
    menu_items = frontend.getAllPopulationNames()
    itemize_view_menu(menu_items, title, depth, symbol)

menu_dic = {
    "Connect to server" : connect_to_server_menu,
    "Setup new schema" : setup_new_schema_menu, 
    "Setup new population" : setup_new_population_menu, 
    "Run task" : run_task_menu, 
    "Stop task" : stop_task_menu,
    "View running tasks" : view_running_tasks_menu,
    "View all schemas" : view_all_schemas_menu,
    "View all populations" : view_all_populations_menu,
    "Run batch tasks" : run_batch_tasks_menu    
}

def main_menu():
    while True:
        item = itemize_menu(initial_main_menu_items, "WELCOME TO DEXEN", 1, ">")
        if item == EXIT:
            return
        menu_dic[item]()
        
if __name__ == "__main__":
    main_menu()
